
#include "MayEvent/event.hpp"
#include <functional>

using namespace std;

EventHandler::EventHandler()
{
}

EventHandler::~EventHandler()
{
}

void EventHandler::addEvnet(std::string eventflag, callbackfunc callback)
{
    eventHandlerMap::iterator obj = this->handles.find(eventflag);

    if (obj == this->handles.end())
    {
        callbackfunclist li = callbackfunclist{callback};
        this->handles.insert({ eventflag, li });
        return;
    }
    obj->second.insert(obj->second.end(), callback);
}

void EventHandler::callEvent(string eventflag)
{
    Argobj<bool> arg = Argobj<bool>();
    this->caller(eventflag, arg);
}

EventHandler& EventHandler::operator<<(const std::string& eventflag)
{
    Argobj<bool> arg = Argobj<bool>();
    this->caller(eventflag, arg);
    return *this;
}

template<typename T>
void EventHandler::callEvent(std::string eventflag, Argobj<T> args)
{
    this->caller(eventflag, args);
}

template<typename T>
void EventHandler::caller(string eventflag, Argobj<T>& args)
{
    eventHandlerMap::iterator obj = this->handles.find(eventflag);
    if (obj != this->handles.end())
    {
        for (auto iter = obj->second.begin(); iter != obj->second.end(); iter++)
        {
            (*iter)(PARGOBJ(new Argobj<T>(args)));
        }
    }
    return;
}

void EventHandler::unRegistEvent(string eventflag, callbackfunc callback)
{
    eventHandlerMap::iterator obj = this->handles.find(eventflag);
    if (obj != this->handles.end())
    {
        callbackfunclist::iterator ifunc = obj->second.find(callback);
        if (ifunc != obj->second.end())
        {
            obj->second.erase(ifunc);
        }
    }
}


// 特化
template void EventHandler::callEvent(std::string eventflag, Argobj<int> args);
template void EventHandler::callEvent(std::string eventflag, Argobj<float> args);
template void EventHandler::callEvent(std::string eventflag, Argobj<double> args);
template void EventHandler::callEvent(std::string eventflag, Argobj<string> args);
template void EventHandler::callEvent(std::string eventflag, Argobj<char> args);
template void EventHandler::callEvent(std::string eventflag, Argobj<ArgPoiner> args);
template void EventHandler::callEvent(std::string eventflag, Argobj<bool> args);
template void EventHandler::callEvent(std::string eventflag, Argobj<unsigned int> args);

template void EventHandler::caller(string eventflag, Argobj<int>& args);
template void EventHandler::caller(string eventflag, Argobj<float>& args);
template void EventHandler::caller(string eventflag, Argobj<double>& args);
template void EventHandler::caller(string eventflag, Argobj<string>& args);
template void EventHandler::caller(string eventflag, Argobj<char>& args);
template void EventHandler::caller(string eventflag, Argobj<ArgPoiner>& args);
template void EventHandler::caller(string eventflag, Argobj<bool>& args);
template void EventHandler::caller(string eventflag, Argobj<unsigned int>& args);
